import assert from 'assert'
import { watchGraphAndLog, watchUnitAndLog } from '../../../debug'
import { fromSpec } from '../../../spec/fromSpec'
import _specs from '../../../system/_specs'
import { system } from '../../util/system'

const spec = require('../../../system/core/loop/RangeReverse/spec.json')
const RangeReverse = fromSpec<{ a: any; b: number }, { i: number }>(
  spec,
  _specs,
  {}
)

const rangeRev = new RangeReverse(system)

false && watchUnitAndLog(rangeRev)
false && watchGraphAndLog(rangeRev)

rangeRev.play()

rangeRev.push('a', 5)
rangeRev.push('b', 5)
assert.equal(rangeRev.take('i'), undefined)
assert.equal(rangeRev.peakInput('a'), undefined)
assert.equal(rangeRev.peakInput('b'), undefined)

rangeRev.push('a', 5)
rangeRev.push('b', 5)
assert.equal(rangeRev.take('i'), undefined)
assert.equal(rangeRev.peakInput('a'), undefined)
assert.equal(rangeRev.peakInput('b'), undefined)

rangeRev.push('a', 2)
rangeRev.push('b', 3)
assert.equal(rangeRev.take('i'), 2)
assert.equal(rangeRev.take('i'), undefined)
assert.equal(rangeRev.peakInput('a'), undefined)
assert.equal(rangeRev.peakInput('b'), undefined)

rangeRev.push('a', 2)
rangeRev.push('b', 3)
assert.equal(rangeRev.take('i'), 2)
assert.equal(rangeRev.take('i'), undefined)
assert.equal(rangeRev.peakInput('a'), undefined)
assert.equal(rangeRev.peakInput('b'), undefined)

rangeRev.push('a', 3)
rangeRev.push('b', 2)
assert.equal(rangeRev.take('i'), undefined)
assert.equal(rangeRev.peakInput('a'), undefined)
assert.equal(rangeRev.peakInput('b'), undefined)

rangeRev.push('a', 2)
rangeRev.push('b', 3)
assert.equal(rangeRev.take('i'), 2)
assert.equal(rangeRev.take('i'), undefined)
assert.equal(rangeRev.peakInput('a'), undefined)
assert.equal(rangeRev.peakInput('b'), undefined)

rangeRev.push('a', 2)
rangeRev.push('b', 4)
assert.equal(rangeRev.take('i'), 3)
assert.equal(rangeRev.take('i'), 2)
assert.equal(rangeRev.take('i'), undefined)
assert.equal(rangeRev.peakInput('a'), undefined)
assert.equal(rangeRev.peakInput('b'), undefined)

rangeRev.push('a', 2)
rangeRev.push('b', 5)
assert.equal(rangeRev.take('i'), 4)
assert.equal(rangeRev.take('i'), 3)
assert.equal(rangeRev.take('i'), 2)
assert.equal(rangeRev.take('i'), undefined)
assert.equal(rangeRev.peakInput('a'), undefined)
assert.equal(rangeRev.peakInput('b'), undefined)

rangeRev.push('a', 2)
rangeRev.push('b', 2)
rangeRev.push('a', 1)
rangeRev.push('b', 1)
assert.equal(rangeRev.take('i'), undefined)
assert.equal(rangeRev.peakInput('a'), undefined)
assert.equal(rangeRev.peakInput('b'), undefined)

rangeRev.push('a', 2)
rangeRev.push('b', 4)
assert.equal(rangeRev.peakInput('a'), 2)
assert.equal(rangeRev.peakInput('b'), 4)
assert.equal(rangeRev.take('i'), 3)
assert.equal(rangeRev.take('i'), 2)
assert.equal(rangeRev.take('i'), undefined)
assert.equal(rangeRev.peakInput('a'), undefined)
assert.equal(rangeRev.peakInput('b'), undefined)

rangeRev.push('a', -2)
rangeRev.push('b', -1)
assert.equal(rangeRev.peakInput('a'), -2)
assert.equal(rangeRev.peakInput('b'), -1)
assert.equal(rangeRev.take('i'), -2)
assert.equal(rangeRev.take('i'), undefined)
assert.equal(rangeRev.peakInput('a'), undefined)
assert.equal(rangeRev.peakInput('b'), undefined)

rangeRev.push('a', 0)
rangeRev.push('b', 2)
assert.equal(rangeRev.peakInput('a'), 0)
assert.equal(rangeRev.peakInput('b'), 2)
assert.equal(rangeRev.peak('i'), 1)
rangeRev.push('a', 1)
assert.equal(rangeRev.take('i'), 1)
assert.equal(rangeRev.peak('i'), undefined)
assert.equal(rangeRev.peakInput('a'), undefined)
assert.equal(rangeRev.peakInput('b'), undefined)

rangeRev.push('a', 0)
rangeRev.push('b', 2)
assert.equal(rangeRev.peakInput('a'), 0)
assert.equal(rangeRev.peakInput('b'), 2)
assert.equal(rangeRev.take('i'), 1)
rangeRev.push('b', 1)
assert.equal(rangeRev.take('i'), 0)
assert.equal(rangeRev.take('i'), undefined)
assert.equal(rangeRev.peakInput('a'), undefined)
assert.equal(rangeRev.peakInput('b'), undefined)

rangeRev.push('a', 0)
rangeRev.push('b', 2)
assert.equal(rangeRev.peakInput('a'), 0)
assert.equal(rangeRev.peakInput('b'), 2)
assert.equal(rangeRev.peak('i'), 1)
rangeRev.push('a', 2)
assert.equal(rangeRev.peak('i'), undefined)
assert.equal(rangeRev.peakInput('a'), undefined)
assert.equal(rangeRev.peakInput('b'), undefined)

rangeRev.push('a', 0)
rangeRev.push('b', 2)
assert.equal(rangeRev.peakInput('a'), 0)
assert.equal(rangeRev.peakInput('b'), 2)
assert.equal(rangeRev.take('i'), 1)
assert.equal(rangeRev.takeInput('b'), 2)
assert.equal(rangeRev.take('i'), undefined)
assert.equal(rangeRev.peakInput('a'), 0)
assert.equal(rangeRev.peakInput('b'), undefined)

rangeRev.setInputConstant('a', true)
rangeRev.push('a', 0)
rangeRev.push('b', 2)
assert.equal(rangeRev.peakInput('a'), 0)
assert.equal(rangeRev.peakInput('b'), 2)
assert.equal(rangeRev.take('i'), 1)
assert.equal(rangeRev.take('i'), 0)
assert.equal(rangeRev.peakInput('a'), 0)
assert.equal(rangeRev.take('i'), undefined)
rangeRev.setInputConstant('a', false)
assert.equal(rangeRev.peakInput('a'), 0)
assert.equal(rangeRev.peakInput('b'), undefined)
rangeRev.push('b', 1)
assert.equal(rangeRev.take('i'), 0)
assert.equal(rangeRev.take('i'), undefined)
assert.equal(rangeRev.peakInput('a'), undefined)
assert.equal(rangeRev.peakInput('b'), undefined)

// // infinite loop
// rangeRev.setInputConstant('a', true)
// rangeRev.setInputConstant('b', true)
// rangeRev.setOutputIgnored('i', true)
// rangeRev.push('a', 0)
// rangeRev.push('b', 1)
